
/**
  ******************************************************************************
  * Copyright 2021 The grapilot Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       storage_manager.c
  * @author     baiyang
  * @date       2021-8-8
  ******************************************************************************
  */

/*----------------------------------include-----------------------------------*/
#include "storage_manager.h"
/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/

/*---------------------------------prototype----------------------------------*/

/*----------------------------------variable----------------------------------*/
static uint8_t buff_mission[STORAGE_MISSION_LENGTH] = {0};
/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
void StorageAccess(StorageAccess_HandleTypeDef *StorageAccess, StorageType type)
{
    StorageAccess->type = type;

    if (StorageAccess->type == StorageMission)
    {
        StorageAccess->total_size = sizeof(buff_mission);
    }
}

// return total size of this accessor
uint16_t StorageAccess_size(StorageAccess_HandleTypeDef *StorageAccess)
{
    return StorageAccess->total_size;
}

/*
  base read function. The src offset is within the bytes allocated
  for the storage type of this StorageAccess object
*/
bool StorageAccess_ReadBlock(StorageAccess_HandleTypeDef *StorageAccess, void *data, uint16_t addr, uint32_t n)
{
    if(n <= 0)
    {
        return false;
    }

    uint8_t *b = (uint8_t *)data;
    for (uint32_t i=0; i<STORAGE_MISSION_LENGTH; i++) {
        if (addr+i >= STORAGE_MISSION_LENGTH)
        {
            return false;
        }
        
        b[i] = buff_mission[addr+i];
        n--;
        if (n == 0) {
            break;
        }
    }
    return (n == 0);
}


/*
  base read function. The addr offset is within the bytes allocated
  for the storage type of this StorageAccess object
*/
bool StorageAccess_WriteBlock(StorageAccess_HandleTypeDef *StorageAccess, uint16_t addr, const void *data, uint32_t n)
{
    if(n <= 0)
    {
        return false;
    }
    
    const uint8_t *b = (const uint8_t *)data;
    for (uint32_t i=0; i<STORAGE_MISSION_LENGTH; i++) {
        if (addr+i >= STORAGE_MISSION_LENGTH)
        {
            return false;
        }
        
        buff_mission[addr+i] = b[i];
        n--;
        if (n == 0) {
            break;
        }
    }
    return (n == 0);
}

/*
  read a byte
 */
uint8_t StorageAccess_ReadByte(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc)
{
    uint8_t v;
    StorageAccess_ReadBlock(StorageAccess, &v, loc, sizeof(v));
    return v;
}

/*
  read 16 bit value
 */
uint16_t StorageAccess_ReadUint16(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc)
{
    uint16_t v;
    StorageAccess_ReadBlock(StorageAccess, &v, loc, sizeof(v));
    return v;
}

/*
  read 32 bit value
 */
uint32_t StorageAccess_ReadUint32(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc)
{
    uint32_t v;
    StorageAccess_ReadBlock(StorageAccess, &v, loc, sizeof(v));
    return v;
}

/*
  write a byte
 */
void StorageAccess_WriteByte(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc, uint8_t value)
{
    StorageAccess_WriteBlock(StorageAccess, loc, &value, sizeof(value));
}

/*
  write a uint16
 */
void StorageAccess_WriteUint16(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc, uint16_t value)
{
    StorageAccess_WriteBlock(StorageAccess, loc, &value, sizeof(value));
}

/*
  write a uint32
 */
void StorageAccess_WriteUint32(StorageAccess_HandleTypeDef *StorageAccess, uint16_t loc, uint32_t value)
{
    StorageAccess_WriteBlock(StorageAccess, loc, &value, sizeof(value));
}

/*------------------------------------test------------------------------------*/


